grammar regexs;

options
{
	language = Python;
}

@parser::header{
import sys
from DeterministicAutomata import *
from Determinizer import *
from AutomataBuilder import *
}
@init{ self.idaut = 1; self.abortar = False; self.automata = None}


@members{ 
def getErrorMessage(self, ruleName, ruleIndex):
    sys.stderr.write('Error al parsear la regex - '+ str(ruleName)+' - ' + str(ruleIndex) + '\n')
    sys.exit(1)
    self.abortar = True

def getTokenErrorDisplay(t):
    sys.stderr.write('Error al parsear la regex - Token - '+ str(t) + '\n')
   
def EarlyExitException(self, d, i):
    sys.stderr.write('Error al parsear la regex - exception - '+ str(d) + ' - '+ str(i) + '\n')
 
def procesar_archivo(self):
    if self.abortar:
        print "abortando"
        sys.exit(1)

    if len(sys.argv)==1:
        print "REGEX ACEPTADA"
        print "Solo aceptando la entrada. Para correr todo ejecutar:"
        print "python eval.py nombreArchivo.txt"
        return
    elif len(sys.argv)==2:
        find_filename = sys.argv[1]
        print "buscar'e en " + find_filename
    else:
        print "Mal llamado, ejecutar con un par'ametro para buscar una regex en un archivo:"
        print "python eval.py nombreArchivo.txt"
        print "o sin par'ametros para aceptar o rechazar una regex:"
        print "python eval.py"
        return

    a = Determinizer(self.automata)
    da = a.determinize()

    da = a.stringuify_set_states(da)
    da.generate_diagram("00-final")

    d = DeterministicAutomata(da)

    f = open(find_filename, 'r')
    ln = 1
    for line in f:
        #print 'Parseando {' + line[:-1] + '}'
        if d.parse(str(line)):
            print 'Match Line '+str(ln)+': ' + str(line),
        else:
        	sys.stderr.write('No acepto la cadena\n')
        ln += 1
}

regex:	{#print "BEGIN"} e {#print "END";}'\n'{self.automata = $e.val; self.procesar_archivo();};

a0 returns [val]:	'('e')' {$val = $e.val}
	| CARACTER { $val = AutomataChar($CARACTER.text,self.idaut);; $val.generate_diagram(str(self.idaut)+"-char"); self.idaut+=1;} 
	| DOT { $val=AutomataDot(self.idaut);; $val.generate_diagram(str(self.idaut)+"-char"); self.idaut+=1;};

a1 returns [val]: 
	a0 {$val = $a0.val; } (OP {
if $OP.text == '+':
    $val = AutomataMas($val, self.idaut)
    $val.generate_diagram(str(self.idaut)+"-autMas")
    self.idaut+=2
if $OP.text == '?':
    $val = AutomataOptional($val, self.idaut)
    $val.generate_diagram(str(self.idaut)+"-autOptional")
    self.idaut+=2
if $OP.text == '*':
    $val = AutomataStar($val, self.idaut)
    $val.generate_diagram(str(self.idaut)+"-autStar")
    self.idaut+=2
} )*; 

a3 returns [val]
@init {$val=AutomataVacio(self.idaut);; $val.generate_diagram(str(self.idaut)+"-empty"); self.idaut+=1;}
    : (a1 { $val=AutomataConcat($val, $a1.val, self.idaut);; $val.generate_diagram(str(self.idaut)+"-concat"); self.idaut+=1;})+ {$val.generate_diagram(str(self.idaut)+"-concat-final")};

a4 returns[val]:	s1=a3 {$val=$s1.val} ('|' s2=a3{$val=AutomataUnion($val, $s2.val, self.idaut);; $val.generate_diagram(str(self.idaut)+"-union"); self.idaut+=1;})*;

e returns[val]
    :		a4 {$val = $a4.val};

OP:		'+' | '?' | '*';
CARACTER:	'a'..'z' | 'A'..'Z' | '0'..'9' | ' ';
DOT:		'.';
